home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Light ROM 1
/
LIGHT-ROM 1 (Amiga Library Services)(1994).iso
/
ffdisks
/
d927.lha
/
Ftp
/
src
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-07
|
10KB
|
594 lines
/*
* Copyright (c) 1985, 1989 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
char copyright[] =
"@(#) Copyright (c) 1985, 1989 Regents of the University of California.\n\
All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)main.c based on 5.13 (Berkeley) 3/14/89";
#endif /* not lint */
/*
* FTP User Program -- Command Interface.
*/
#define FTPVARS
#include "ftp_var.h"
#include <sys/socket.h>
#ifdef AMI_TCP
#include <bsdsocket.h>
#else
#include <ss/socket.h>
#endif
#include <sys/ioctl.h>
#include <sys/types.h>
#include <arpa/ftp.h>
#include <signal.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <netdb.h>
#ifndef AMI_TCP
#include <pwd.h>
#endif
//#include <syslog.h>
#ifdef __SASC
int Enable_Abort;
#endif
#if defined(sun) && !defined(FD_SET)
typedef int uid_t;
#endif
sig_t intr();
sig_t lostpeer();
char *getlogin();
extern char *home;
struct Library *OpenLibrary();
#ifdef AMI_TCP
struct Library *SocketBase=0;
#else
struct Library *SockBase=0;
#endif
FILE *log_file = 0;
shut_down()
{
if (log_file) fclose(log_file);
log_file = 0;
#ifdef AMI_TCP
if (SocketBase)
CloseLibrary(SocketBase);
SocketBase = 0;
#else
if (SockBase)
{ cleanup_sockets();
CloseLibrary(SockBase);
}
SockBase = 0;
#endif
}
extern int Enable_Abort;
main(argc, argv)
char *argv[];
{
register char *cp;
int top;
extern char *mygetenv();
#ifdef AMI_TCP
SocketBase = OpenLibrary("bsdsocket.library",0L);
SetErrnoPtr(&errno,sizeof(errno));
#else
SockBase = OpenLibrary("inet:libs/socket.library",0L);
setup_sockets(5,&errno);
#endif
atexit(shut_down);
sp = getservbyname("ftp", "tcp");
if (sp == 0) {
fprintf(stderr, "ftp: ftp/tcp: unknown service\n");
exit(1);
}
doglob = 0;
interactive = 1;
hash = 0;
logname = 0;
autologin = 1;
#ifdef FTP_LOG_USAGE
#ifdef LOG_LOCAL3
openlog("ftp", LOG_PID, LOG_LOCAL3);
#else
openlog("ftp", LOG_PID);
#endif /* LOG_LOCAL2 */
#endif /* FTP_LOG_USAGE */
argc--, argv++;
while (argc > 0 && **argv == '-') {
for (cp = *argv + 1; cp && *cp; cp++)
switch (*cp) {
case 'd':
options |= SO_DEBUG;
debug++;
break;
case 'v':
verbose++;
break;
case 't':
trace++;
break;
case 'i':
interactive = 0;
break;
case 'n':
autologin = 0;
break;
case 'g':
doglob = 0;
break;
case 'L':
logname = cp+1;
cp = 0;
break;
case 'H':
hash = 1;
break;
case 'D':
dldir = cp+1;
cp = 0;
break;
case 'U':
uldir = cp+1;
cp = 0;
break;
default:
fprintf(stdout,
"ftp: %c: unknown option\n", *cp);
exit(1);
}
argc--, argv++;
}
fromatty = isatty(fileno(stdin));
/*
* Set up defaults for FTP.
*/
(void) strcpy(typename, "ascii"), type = TYPE_A;
(void) strcpy(formname, "non-print"), form = FORM_N;
(void) strcpy(modename, "stream"), mode = MODE_S;
(void) strcpy(structname, "file"), stru = STRU_F;
(void) strcpy(bytename, "8"), bytesize = 8;
if (fromatty)
verbose++;
cpend = 0; /* no pending replies */
proxy = 0; /* proxy not active */
crflag = 1; /* strip c.r. on ascii gets */
/*
* Set up the home directory in case we're globbing.
*/
if (uldir == 0 || dldir == 0)
{ char currentdir[MAXPATHLEN];
getcwd(currentdir,MAXPATHLEN);
if (uldir == 0) uldir = currentdir;
if (dldir == 0) dldir = currentdir;
}
if (logname)
log_file = fopen(logname,"a");
home = uldir;
if (argc > 0) {
if (setjmp(toplevel))
exit(0);
#ifndef __SASC
(void) signal(SIGINT, intr);
(void) signal(SIGPIPE, lostpeer);
#endif
setpeer(argc + 1, argv - 1);
}
else
{ printf("[FTP] ");
strcpy(line,"open");
makeargv();
if (setjmp(toplevel) == 0) {
#ifndef __SASC
(void) signal(SIGINT, intr);
(void) signal(SIGPIPE, lostpeer);
#endif
setpeer(margc,margv);
}
}
top = setjmp(toplevel) == 0;
if (top) {
#ifndef __SASC
(void) signal(SIGINT, intr);
(void) signal(SIGPIPE, lostpeer);
#endif
}
for (;;) {
cmdscanner(top);
top = 1;
}
}
sig_t
intr()
{
longjmp(toplevel, 1);
}
sig_t
lostpeer()
{
extern int cout;
extern int data;
if (connected) {
if (cout >= 0) {
(void) shutdown(cout, 1+1);
(void) s_close(cout);
cout = -1;
}
if (data >= 0) {
(void) shutdown(data, 1+1);
(void) s_close(data);
data = -1;
}
connected = 0;
}
pswitch(1);
if (connected) {
if (cout >= 0) {
(void) shutdown(cout, 1+1);
(void) s_close(cout);
cout = -1;
}
connected = 0;
}
proxflag = 0;
pswitch(0);
}
/*char *
tail(filename)
char *filename;
{
register char *s;
while (*filename) {
s = rindex(filename, '/');
if (s == NULL)
break;
if (s[1])
return (s + 1);
*s = '\0';
}
return (filename);
}
*/
/*
* Command parser.
*/
cmdscanner(top)
int top;
{
register struct cmd *c;
struct cmd *getcmd();
extern int help();
if (!top)
(void) putchar('\n');
for (;;) {
if (fromatty) {
printf("ftp> ");
(void) fflush(stdout);
}
if (gets(line) == 0) {
if (feof(stdin) || ferror(stdin))
quit();
break;
}
if (line[0] == 0)
break;
makeargv();
if (margc == 0) {
continue;
}
c = getcmd(margv[0]);
if (c == (struct cmd *)-1) {
printf("?Ambiguous command\n");
continue;
}
if (c == 0) {
printf("?Invalid command\n");
continue;
}
if (c->c_conn && !connected) {
printf ("Not connected.\n");
continue;
}
(*c->c_handler)(margc, margv);
if (bell && c->c_bell)
(void) putchar('\007');
if (c->c_handler != help)
break;
}
#ifndef __SASC
(void) signal(SIGINT, intr);
(void) signal(SIGPIPE, lostpeer);
#endif
}
struct cmd *
getcmd(name)
register char *name;
{
extern struct cmd cmdtab[];
register char *p, *q;
register struct cmd *c, *found;
register int nmatches, longest;
longest = 0;
nmatches = 0;
found = 0;
for (c = cmdtab; p = c->c_name; c++) {
for (q = name; *q == *p++; q++)
if (*q == 0) /* exact match? */
return (c);
if (!*q) { /* the name was a prefix */
if (q - name > longest) {
longest = q - name;
nmatches = 1;
found = c;
} else if (q - name == longest)
nmatches++;
}
}
if (nmatches > 1)
return ((struct cmd *)-1);
return (found);
}
/*
* Slice a string up into argc/argv.
*/
int slrflag;
makeargv()
{
char **argp;
char *slurpstring();
margc = 0;
argp = margv;
stringbase = line; /* scan from first of buffer */
argbase = argbuf; /* store from first of buffer */
slrflag = 0;
while (*argp++ = slurpstring())
margc++;
}
/*
* Parse string into argbuf;
* implemented with FSM to
* handle quoting and strings
*/
char *
slurpstring()
{
int got_one = 0;
register char *sb = stringbase;
register char *ap = argbase;
char *tmp = argbase; /* will return this if token found */
if (*sb == '!' || *sb == '$') { /* recognize ! as a token for shell */
switch (slrflag) { /* and $ as token for macro invoke */
case 0:
slrflag++;
stringbase++;
return ((*sb == '!') ? "!" : "$");
/* NOTREACHED */
case 1:
slrflag++;
altarg = stringbase;
break;
default:
break;
}
}
S0:
switch (*sb) {
case '\0':
goto OUT;
case ' ':
case '\t':
sb++; goto S0;
default:
switch (slrflag) {
case 0:
slrflag++;
break;
case 1:
slrflag++;
altarg = sb;
break;
default:
break;
}
goto S1;
}
S1:
switch (*sb) {
case ' ':
case '\t':
case '\0':
goto OUT; /* end of token */
case '\\':
sb++; goto S2; /* slurp next character */
case '"':
sb++; goto S3; /* slurp quoted string */
default:
*ap++ = *sb++; /* add character to token */
got_one = 1;
goto S1;
}
S2:
switch (*sb) {
case '\0':
goto OUT;
default:
*ap++ = *sb++;
got_one = 1;
goto S1;
}
S3:
switch (*sb) {
case '\0':
goto OUT;
case '"':
sb++; goto S1;
default:
*ap++ = *sb++;
got_one = 1;
goto S3;
}
OUT:
if (got_one)
*ap++ = '\0';
argbase = ap; /* update storage pointer */
stringbase = sb; /* update scan pointer */
if (got_one) {
return(tmp);
}
switch (slrflag) {
case 0:
slrflag++;
break;
case 1:
slrflag++;
altarg = (char *) 0;
break;
default:
break;
}
return((char *)0);
}
#define HELPINDENT (sizeof ("directory"))
/*
* Help command.
* Call each command handler with argc == 0 and argv[0] == name.
*/
help(argc, argv)
int argc;
char *argv[];
{
extern struct cmd cmdtab[];
register struct cmd *c;
if (argc == 1) {
register int i, j, w, k;
int columns, width = 0, lines;
extern int NCMDS;
printf("Commands may be abbreviated. Commands are:\n\n");
for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
int len = strlen(c->c_name);
if (len > width)
width = len;
}
width = (width + 8) &~ 7;
columns = 80 / width;
if (columns == 0)
columns = 1;
lines = (NCMDS + columns - 1) / columns;
for (i = 0; i < lines; i++) {
for (j = 0; j < columns; j++) {
c = cmdtab + j * lines + i;
if (c->c_name && (!proxy || c->c_proxy)) {
printf("%s", c->c_name);
}
else if (c->c_name) {
for (k=0; k < strlen(c->c_name); k++) {
(void) putchar(' ');
}
}
if (c + lines >= &cmdtab[NCMDS]) {
printf("\n");
break;
}
w = strlen(c->c_name);
while (w < width) {
w = (w + 8) &~ 7;
(void) putchar('\t');
}
}
}
return;
}
while (--argc > 0) {
register char *arg;
arg = *++argv;
c = getcmd(arg);
if (c == (struct cmd *)-1)
printf("?Ambiguous help command %s\n", arg);
else if (c == (struct cmd *)0)
printf("?Invalid help command %s\n", arg);
else
printf("%-*s\t%s\n", HELPINDENT,
c->c_name, c->c_help);
}
}